#include "cards.h"
#include <QRandomGenerator>
Cards::Cards() {}

Cards::Cards(const Card &card)
{
    Add(card);
}

void Cards::Add(const Card &card)
{
    cards_.insert(card);
}

void Cards::Add(const Cards &cards)
{
    cards_.unite(cards.cards_);
}


Cards &Cards::operator <<(const Card &card)
{
    Add(card);
    return *this;
}

Cards &Cards::operator <<(const Cards &cards)
{
    Add(cards);
    return *this;
}


void Cards::remove(const Card &card)
{
    cards_.remove(card);
}

void Cards::remove(const Cards &cards)
{
    cards_.subtract(cards.cards_);
}

std::size_t Cards::Card_Count() const
{
    return cards_.size();
}

bool Cards::Is_Empty() const
{
    return cards_.empty();
}

void Cards::Clear()
{
    return cards_.clear();
}

Card::CardPoint Cards::Max_Point() const
{
    Card::CardPoint max = Card::CardPoint::Card_Begin;
    if(!Is_Empty())
    {
        for(auto it = cards_.begin(); it != cards_.end(); ++it)
        {
            if(it->Get_Point() > max)
            {
                max = it->Get_Point();
            }
        }
    }
    return max;
}

Card::CardPoint Cards::Min_Point() const
{
    Card::CardPoint min = Card::CardPoint::Card_End;
    if(!Is_Empty())
    {
        for(auto it = cards_.begin(); it != cards_.end(); ++it)
        {
            if(it->Get_Point() < min)
            {
                min = it->Get_Point();
            }
        }
    }
    return min;
}

std::size_t Cards::Point_Count(Card::CardPoint point) const
{
    std::size_t count = 0;
    for(auto it = cards_.begin(); it != cards_.end(); ++it)
    {
        if(it->Get_Point() == point)
        {
            ++count;
        }
    }
    return count;
}

bool Cards::Contains(const Card &card)
{
    return cards_.contains(card);
}

bool Cards::Contains(const Cards &cards)
{
    return cards_.contains(cards.cards_);
}

Card Cards::Take_RandCard()
{
    int randnum = QRandomGenerator::global()->bounded(cards_.size());
    QSet<Card>::const_iterator it = cards_.constBegin();
    for(int i = 0; i < randnum; ++i,++it);
    Card card = *it;
    cards_.erase(it);
    return card;
}

CardList Cards::To_CardList(SortType type)
{
    CardList list;
    for(auto it = cards_.begin(); it != cards_.end(); ++it)
    {
        list << *it;
    }

    if(type == Asc)
    {
        std::sort(list.begin(),list.end(),[](const Card&left,const Card&right)->bool
                                             {
                                              return left.Get_Point() == right.Get_Point()?
                                                     left.Get_Suit() < right.Get_Suit():
                                                     left.Get_Point() < right.Get_Point();
                                             });

    }
    else if(type == Desc)
    {
        std::sort(list.begin(),list.end(),[](const Card&left,const Card&right)->bool
                                          {
                                              return left.Get_Point() == right.Get_Point()?
                                                     left.Get_Suit() > right.Get_Suit():
                                                     left.Get_Point() > right.Get_Point();
                                          });
    }

    return list;
}



